#ifndef  LEXCAL_H_
#define  LEXCAL_H_
#include  <cstdlib>
#include  <string>
#include  <vector>
#include  <cctype>
#include  <iostream>

using namespace std;

// class to process the expr
// Author : Junix(sjtu)
// Date   : 2007-03-31

bool    left_match(string src, string target);
bool    right_match(string src, string target);
bool    left_sub(string &src, string target);
bool    right_sub(string &src, string target);
string  cell(string& attr, char token);
int     clean(string& attr);
void    right_clean(string& attr);
vector<string> str_to_vector(string tuple, char token);


//get a cell from file
string cell(string& attr, char token)
{
    right_clean(attr);
    clean(attr);
    if (attr.size()==0)
    {
        cerr<<"error: attributes config file empty."<<endl;
        exit(1);
    }

    string cell;
    string::size_type idx = attr.find(token);
    if (idx == string::npos)
    {
        cell = attr;
        attr.clear();
        return cell;
    }
    else
    {
        cell   =  attr.substr(0, idx);
        if (attr.size() != idx+1)
        {
            attr =  attr.substr(idx+1);
            clean(attr);
        }
        else
        {
            attr.clear();
        }
        return cell;
    }
}

//make vector
vector<string> str_to_vector(string tuple, char token)
{
    vector<string> re;
    while (!tuple.empty())
    {
        re.push_back(cell(tuple,token));
    }
    return re;
}

//remove space
int clean(string& attr)
{
    while (!attr.empty() && isspace(attr.at(0)))
        attr.erase(0,1);
    return 0;
}

void right_clean(string& attr)
{
    while (!attr.empty() && isspace(attr.at(attr.size()-1)))
        attr.erase(attr.size()-1,attr.size());
}

int clean(string& attr, string token)
{
    while (left_match(attr,token))
        left_sub(attr,token);

    while (right_match(attr,token))
        right_sub(attr,token);

    return 0;
}

//left match
bool left_match(string src, string target)
{
    if (src.length() < target.length())
        return false;

    string sub = src.substr(0, target.length());
    if ( sub.compare(target) == 0 )
        return true;
    else
        return false;
}

// right match
bool right_match(string src, string target)
{
    if (src.length() < target.length())
        return false;

    string sub = src.substr(src.length() - target.length());
    if ( sub.compare(target) == 0 )
        return true;
    else
        return false;
}

//sub the left
bool left_sub(string &src, string target)
{
    if (!left_match(src, target))
        return false;

    src = src.substr(target.length());
    return true;
}

// sub the right
bool right_sub(string &src, string target)
{
    if (!right_match(src, target))
        return false;

    src = src.substr(0, src.length()- target.length());
    return true;
}


#endif
